package com.xb.loan.encryptor.mina.handler;


import com.xb.loan.encryptor.bean.LotteryBean;
import com.xb.loan.encryptor.bean.Packet;
import com.xb.loan.encryptor.handler.BussinessHandler;
import com.xb.loan.encryptor.handler.HandlerManagerFactory;
import com.xb.loan.encryptor.util.LotteryBeanHelper;
import com.xb.loan.util.binaryConvert.BinaryParseUtil;
import com.xb.loan.util.binaryConvert.CryptUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.session.IoSession;

import java.util.LinkedList;
import java.util.List;

public class CryptographyServerHandler extends ConfineServerHandler {
	
	private static Log log = LogFactory.getLog(CryptographyServerHandler.class);
	
	@Override
	public void messageReceived(IoSession ioSession, Object o) throws Exception {
		
		long time = System.currentTimeMillis();
		
		Packet packet = (Packet) o;
		
		log.info("recevice msg from " + ioSession.getRemoteAddress() + ",transcode:" + packet.getTranscode());
		
		byte[] packetBody = convert(packet.getPacketBody());
		
		byte[] body = new byte[packetBody.length - 1];
		// 解密消息体
		CryptUtil.decode(packetBody, body, packetBody.length);
		
		LotteryBean lotteryBean = BinaryParseUtil.convert(body, LotteryBeanHelper.getTransCodeClass(packet.getTranscode()));
		
		BussinessHandler handler = HandlerManagerFactory.getHandlerManager(HandlerManagerFactory.DEFAULT_HANDLER_VERSION).getHandler(packet.getTranscode());
		// 处理业务
		LotteryBean response = handler.doBussiness(lotteryBean);
		
		log.info("send msg to " + ioSession.getRemoteAddress() + ",transcode:" + response.getHead().getTranscode() + ",use:" + (System.currentTimeMillis() - time));
		
		ioSession.write(convert(response));
	}

	private Packet convert(LotteryBean response) {
		
		Packet p = new Packet();
		
		p.setProtocolMajor((byte) 1);
		p.setProtocolMinor((byte) 0);
		p.setTranscode(response.getHead().getTranscode());
		
		byte[] body = BinaryParseUtil.format(response);
		
		byte[] bodyCrypt = new byte[body.length + 1];
		
		CryptUtil.encode(body, bodyCrypt, body.length);
		
		List<Byte> packetBody = new LinkedList<Byte>();
		
		for (int i = 0; i < bodyCrypt.length; i++) {
			
			packetBody.add(bodyCrypt[i]);
		}
		
		p.setPacketBody(packetBody);
		
		return p;
	}

	private byte[] convert(List<Byte> packetBody) {
		
		byte[] data = new byte[packetBody.size()];
		
		for (int i = 0; i < data.length; i++) {
			data[i] = packetBody.get(i);
		}
		
		return data;
	}
	
}
